﻿using MiniFox.Data.Mapping;
using MiniFox.Infrastructure;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;

namespace MiniFox.Data
{
    /// <summary>
    /// 扩展的DataRow泛型对象
    /// </summary>
    public class XDataRow : DataRow
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="rowBuilder"></param>
        internal XDataRow(DataRowBuilder rowBuilder) : base(rowBuilder)
        {
        }
        /// <summary>
        /// 
        /// </summary>
        public new XDataTable Table
        {
            get { return ((XDataTable)(base.Table)); }
        }
        /// <summary>
        /// 
        /// </summary>
        public int RowIndex { get; set; }

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="dataRow"></param>
        //public static implicit operator RowItem(XDataRow dataRow)
        //{
        //    Dictionary<string, object> dict = dataRow;
        //    var rowItem = new RowItem
        //    {
        //        RowIndex = dataRow.RowIndex,
        //        RowState = dataRow.RowState,
        //        Data = dict
        //    };

        //    return rowItem;
        //}
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataRow"></param>
        public static implicit operator Dictionary<string, object>(XDataRow dataRow)
        {
            var dataTable = dataRow.Table;
            Dictionary<string, object> dict = new Dictionary<string, object>();
            foreach (DataColumn column in dataTable.Columns)
            {
                dict.Add(column.ColumnName, dataRow[column.ColumnName]);
            }
            return dict;
        }
    }
    /// <summary>
    /// 扩展的DataRow泛型对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class XDataRow<T> : DataRow
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="rowBuilder"></param>
        internal XDataRow(DataRowBuilder rowBuilder) : base(rowBuilder)
        {
        }
        /// <summary>
        /// 
        /// </summary>
        public new XDataTable<T> Table
        {
            get { return ((XDataTable<T>)(base.Table)); }
        }
        /// <summary>
        /// 
        /// </summary>
        public int RowIndex { get; set; }

        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="dataRow"></param>
        //public static implicit operator RowItem(XDataRow<T> dataRow)
        //{
        //    T t = dataRow;
        //    var rowItem = new RowItem
        //    {
        //        RowIndex = dataRow.RowIndex,
        //        RowState = dataRow.RowState,
        //        Data = t
        //    };

        //    return rowItem;
        //}
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataRow"></param>
        /// <returns></returns>
        public static implicit operator T(XDataRow<T> dataRow)
        {
            if (dataRow == null)
                return default;

            Type type = typeof(T);
            T entity = (T)type.Assembly.CreateInstance(type.FullName);
            ITableMapping tableMapping;
            tableMapping = TableMapping.GetTableMapping(type);

            foreach (IColumnMapping mapping in tableMapping.ColumnMappings)
            {
                PropertyInfo property = type.GetProperty(mapping.DataSetColumn);
                object val = dataRow[mapping.SourceColumn];
                if (val == DBNull.Value)
                    val = null;
                property.SetValue(entity, dataRow[mapping.SourceColumn]);
            }
            return entity;
        }

    }
}
